
package com.example.filetransfer;

import android.app.Service;
import android.content.Intent;
import android.os.Binder;
import android.os.IBinder;
import android.util.Log;

import com.example.filetransfer.connection.ClientListener;
import com.example.filetransfer.connection.ClientListener.Server;
import com.example.filetransfer.connection.ConnectionManager;
import com.example.filetransfer.connection.ConnectionManager.OnConnectedListener;
import com.example.filetransfer.publicsource.connection.DataReceiver.onReceiveMessageListener;
import com.example.filetransfer.publicsource.connection.FileTransferListener;
import com.example.filetransfer.publicsource.connection.Protocol;
import com.example.filetransfer.publicsource.fileutils.DirUtils;

import java.io.FileNotFoundException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class FileTransferService extends Service implements FileTransferListener,
        onReceiveMessageListener {
    private static final String TAG = "FileTransferService";
    public static final String SYNC_FROM_PC_ACTION = "com.yadong.test.syncfrompc";
    public static final String SYNC_TO_PC_ACTION = "com.yadong.test.synctopc";
    private static final String PREFERENCE_DATA = "data.xml";
    private static final String PREFERENCE_NAME_FILEVERSION = "fileversion";
    private static final String EXTERNAL_SYNC_DIR = "/storage/emulated/legacy/Android/Data/com.example.filetransfer/files/syncs";

    private FileTransferListener mFileTransferListener;

    private ConnectionManager mConnectionManager = null;

    @Override
    public void onCreate() {
        super.onCreate();
        mConnectionManager = ConnectionManager.getInstance();
        mConnectionManager.setReceiveMessageListener(this);
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        mConnectionManager.close();
        mWoker.shutdown();
    }

    public void doWork(String action) {
        // No file in phone
        if (getFileVersionString() == null) {
            sendMessage(Protocol.MESSAGE_SEND_ME_YOUR_ALL_FILES);
        } else {
            sendMessage(Protocol.MESSAGE_SEND_ME_YOUR_FILE_VERSION);
        }
    }

    public void startConnection(Server server, OnConnectedListener connectedListener) {
        mConnectionManager.startConnection(server, connectedListener);
    }

    public void sendMessage(String message) {
        mConnectionManager.sendMessageToTarget(message);
    }

    public List<Server> getServerList() {
        return mConnectionManager.getServerList();
    }

    public void setClientListener(ClientListener clientListener) {
        mConnectionManager.setClientListener(clientListener);
    }

    public void requestConnection() {
        mConnectionManager.requestClientConnect();
        Log.d(TAG, "request for client connection and wait");
    }

    public void setReceiveMessageListener(onReceiveMessageListener messageListener) {
//        mConnectionManager.setReceiveMessageListener(messageListener);
    }

    public void setFileTransferListener(FileTransferListener fileTransferListener) {
        mConnectionManager.setFileTransferListener(fileTransferListener);
    }

    private void sendFile(String file, FileTransferListener listener) throws FileNotFoundException {
        mConnectionManager.sendFile(file, listener);
    }

    public void sendFiles(String[] filesPath, FileTransferListener fileTransferListener)
            throws FileNotFoundException {
        sendMessage("SEND_FILEs:file size = " + filesPath.length
                + " all file length=" + 100);
        for (String file : filesPath) {
            sendFile(file, fileTransferListener);
        }
    };

    @Override
    public IBinder onBind(Intent intent) {
        return mBinder;
    }

    private MyBinder mBinder = new MyBinder();

    public class MyBinder extends Binder {
        public FileTransferService getService() {
            return FileTransferService.this;
        }
    }

    private String getFileVersionString() {
        String currentVersion = getSharedPreferences(PREFERENCE_DATA, MODE_PRIVATE).getString(
                PREFERENCE_NAME_FILEVERSION, null);
        return currentVersion;
    }

    private String writeFileVersion(String version) {
        if (version == null) {
            version = Long.toString(System.currentTimeMillis());
        }
        getSharedPreferences(PREFERENCE_DATA, MODE_PRIVATE).edit()
                .putString(PREFERENCE_NAME_FILEVERSION, version).commit();
        return version;
    }

    private ExecutorService mWoker = Executors.newSingleThreadExecutor();

    @Override
    public void receiveMessage(String message) {
        Log.d(TAG, "receive message:" + message);
        if (Protocol.replyFileSendDone(message)) {
            String version = message.substring(message.indexOf(":") + 1);
            writeFileVersion(version);
        } else if (Protocol.replyFileVersion(message)) {
            String version = message.substring(message.indexOf(":") + 1);
            if (compareVersion(version) < 0) {
                sendMessage(Protocol.MESSAGE_CLIENT_NEW);
            } else if (compareVersion(version) > 0) {
                sendMessage(Protocol.MESSAGE_SERVER_NEW);
            }
            DirUtils.writeNewTree(EXTERNAL_SYNC_DIR);
            try {
                sendFile(DirUtils.createFile(EXTERNAL_SYNC_DIR, Protocol.FILETREENAME),
                        new FileTransferListener() {
                            @Override
                            public void onProgressChanged(String fileUrl, int progress) {
                                if (progress == 100) {
                                    sendMessage(Protocol.MESSAGE_SEND_MY_FILETREE_DONE);
                                }
                            }
                        });
            } catch (FileNotFoundException e) {
                e.printStackTrace();
            }
        } else if (Protocol.replySendFileToMe(message)) {
            String content = message.substring(message.indexOf(":") + 1);
            String [] paths = changeMessageToList(content);
            for (String path : paths) {
                try {
                    sendFile(path, mFileTransferListener);
                } catch (FileNotFoundException e) {
                    e.printStackTrace();
                }
            }
            String newVersion = Long.toString(System.currentTimeMillis());
            writeFileVersion(newVersion);
            sendMessage(Protocol.REPLY_SEND_FILE_DONE_PREFIX + newVersion);
        } else if (Protocol.MESSAGE_SYNC_DONE.equals(message)) {
            //DONE
        } 
    }

    private String[] changeMessageToList(String message) {
        String paths[] = message.split(Protocol.FILE_SPLITER);
        return paths;
    }

    private int compareVersion(String remoteVersion) {
        return remoteVersion.compareTo(getFileVersionString());
    }

    @Override
    public void onProgressChanged(String fileUrl, int progress) {
        if (mFileTransferListener != null) {
            mFileTransferListener.onProgressChanged(fileUrl, progress);
        }
    }

}
